; sound.asm
; sound routines for 8play

	.include "global.inc"

	_IN_SOUND = 1
	.include "sound.inc"

	CHANNEL1 = VIC_BASE+10
	CHANNEL2 = VIC_BASE+11
	CHANNEL3 = VIC_BASE+12
	CHANNEL4 = VIC_BASE+13
	VOLUME = VIC_BASE+14

	.segment "ZEROPAGE"

snd1ptr:	.res 2
snd2ptr:	.res 2
snd3ptr:	.res 2
snd4ptr:	.res 2

	.segment "DATA"

snd1nxt:	.word 0
snd2nxt:	.word 0
snd3nxt:	.word 0
snd4nxt:	.word 0

snd1flg:	.byte 0
snd2flg:	.byte 0
snd3flg:	.byte 0
snd4flg:	.byte 0

snd1cnt:	.byte 0
snd2cnt:	.byte 0
snd3cnt:	.byte 0
snd4cnt:	.byte 0

snd1idx:	.byte 0
snd2idx:	.byte 0
snd3idx:	.byte 0
snd4idx:	.byte 0

	.segment "CODE"
	
soundirq:	lda snd1flg			; flg?
			beq @no_ch1			; 0 -> done
			dec snd1cnt			; cnt--
			bne @no_ch1			; > 0 -> done
@outsnd1:	ldy snd1idx			; A := snd1ptr[snd1idx]
			lda (snd1ptr), y
			bne @noz1			; <> 0 -> use
			ldx snd1nxt+1		; nextptr
			beq @done1			; = NULL -> end sound 			
			sta snd1idx
			sta snd1cnt
			inc snd1cnt
			cp16 snd1nxt, snd1ptr
			ld16 snd1nxt, 0
			jmp @outsnd1
@done1:		sta snd1flg			; end sound
			sta CHANNEL1
			beq @no_ch1			
@noz1:		sta snd1cnt			; snd1cnt := A (snd1ptr[snd1idx])
			iny					; A := snd1ptr[snd1idx+1]
			lda (snd1ptr), y
			sta CHANNEL1		; (CHANNEL1) := A
			iny					; snd1idx += 2
			sty snd1idx	
@no_ch1:	lda snd2flg
			beq @no_ch2
			
			dec snd2cnt			; cnt--
			bne @no_ch2			; > 0 -> done
@outsnd2:	ldy snd2idx			; A := snd1ptr[snd1idx]
			lda (snd2ptr), y
			bne @noz2			; <> 0 -> use
			ldx snd2nxt+1		; nextptr
			beq @done2			; = NULL -> end sound 			
			sta snd2idx
			sta snd2cnt
			inc snd2cnt
			cp16 snd2nxt, snd2ptr
			ld16 snd2nxt, 0
			jmp @outsnd2
@done2:		sta snd2flg			; end sound
			sta CHANNEL2
			beq @no_ch2			
@noz2:		sta snd2cnt			; snd1cnt := A (snd1ptr[snd1idx])
			iny					; A := snd1ptr[snd1idx+1]
			lda (snd2ptr), y
			sta CHANNEL2		; (CHANNEL1) := A
			iny					; snd1idx += 2
			sty snd2idx	
			
@no_ch2:	lda snd3flg
			beq @no_ch3
			
			dec snd3cnt			; cnt--
			bne @no_ch3			; > 0 -> done
@outsnd3:	ldy snd3idx			; A := snd1ptr[snd1idx]
			lda (snd3ptr), y
			bne @noz3			; <> 0 -> use
			ldx snd3nxt+1		; nextptr
			beq @done3			; = NULL -> end sound 			
			sta snd3idx
			sta snd3cnt
			inc snd3cnt
			cp16 snd3nxt, snd3ptr
			ld16 snd3nxt, 0
			jmp @outsnd3
@done3:		sta snd3flg			; end sound
			sta CHANNEL3
			beq @no_ch3			
@noz3:		sta snd3cnt			; snd1cnt := A (snd1ptr[snd1idx])
			iny					; A := snd1ptr[snd1idx+1]
			lda (snd3ptr), y
			sta CHANNEL3		; (CHANNEL1) := A
			iny					; snd1idx += 2
			sty snd3idx	
			
@no_ch3:	lda snd4flg
			beq @no_ch4

			dec snd4cnt			; cnt--
			bne @no_ch4			; > 0 -> done
@outsnd4:	ldy snd4idx			; A := snd1ptr[snd1idx]
			lda (snd4ptr), y
			bne @noz4			; <> 0 -> use
			ldx snd4nxt+1		; nextptr
			beq @done4			; = NULL -> end sound 			
			sta snd4idx
			sta snd4cnt
			inc snd4cnt
			cp16 snd4nxt, snd4ptr
			ld16 snd4nxt, 0
			jmp @outsnd4
@done4:		sta snd4flg			; end sound
			sta CHANNEL4
			beq @no_ch4			
@noz4:		sta snd4cnt			; snd1cnt := A (snd1ptr[snd1idx])
			iny					; A := snd1ptr[snd1idx+1]
			lda (snd4ptr), y
			sta CHANNEL4		; (CHANNEL1) := A
			iny					; snd1idx += 2
			sty snd4idx	
			
@no_ch4:	rts

soundoff:	lda #0
			php
			sei
			sta snd1flg
			sta snd2flg
			sta snd3flg
			sta snd4flg
			plp
			sta VOLUME
			sta CHANNEL1
			sta CHANNEL2
			sta CHANNEL3
			sta CHANNEL4
			rts
			
setvol:		; A .. volume
			sta VOLUME
			rts

.macro select_sound
			lda sndtbllo, y
			sta soundptr
			lda sndtblhi, y
			sta soundptr+1 
.endmacro

sound1:		; Y .. index
			select_sound
			php
			sei
			lda snd1flg
			bne @chknxt
			cp16 soundptr, snd1ptr
			ld16 snd1nxt, 0
			lda #1
			sta snd1cnt
			lda #0
			sta snd1idx
			beq @done
@chknxt:	cp16 soundptr, snd1nxt
@done:		lda #1
			sta snd1flg 
			plp
			rts

sound2:		; Y .. index
			select_sound
			php
			sei
			lda snd2flg
			bne @chknxt
			cp16 soundptr, snd2ptr
			ld16 snd2nxt, 0
			lda #1
			sta snd2cnt
			lda #0
			sta snd2idx
			beq @done
@chknxt:	cp16 soundptr, snd2nxt
@done:		lda #1
			sta snd2flg 
			plp
			rts
			
sound3:		; Y .. index
			select_sound
			php
			sei
			lda snd3flg
			bne @chknxt
			cp16 soundptr, snd3ptr
			ld16 snd3nxt, 0
			lda #1
			sta snd3cnt
			lda #0
			sta snd3idx
			beq @done
@chknxt:	cp16 soundptr, snd3nxt
@done:		lda #1
			sta snd3flg 
			plp
			rts
			
sound4:		; Y .. index
			select_sound
			php
			sei
			lda snd4flg
			bne @chknxt
			cp16 soundptr, snd4ptr
			ld16 snd4nxt, 0
			lda #1
			sta snd4cnt
			lda #0
			sta snd4idx
			beq @done
@chknxt:	cp16 soundptr, snd4nxt
@done:		lda #1
			sta snd4flg 
			plp
			rts
			
	.segment "DATA"
	
soundptr:	.word sndsteps

	.segment "RODATA"

sndtbllo:	.byte <sndsteps, <sndthud, <sndblip, <sndnoise, <sndgo, <sndover
sndtblhi:	.byte >sndsteps, >sndthud, >sndblip, >sndnoise, >sndgo, >sndover
	
sndsteps:	.byte 2, 200, 2, 0, 0
sndthud:	.byte 4, 160, 1, 0, 0	
sndblip:	.byte 1, 250, 1, 245, 1, 240, 1, 235, 1, 230, 1, 225, 0 
sndnoise:	.byte 4, 220, 3, 210, 2, 200, 1, 0, 0
sndgo:		.byte 1, 225, 1, 227, 1, 228, 1, 229, 1, 231, 1, 232, 1, 233, 2, 235, 1, 236, 1, 237, 1, 239, 1, 240, 0
sndover:	.byte 1, 225, 1, 223, 2, 225, 2, 227, 3, 225, 3, 223, 4, 225, 4, 227, 8, 225, 0
